home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / memory.c < prev    next >
C/C++ Source or Header  |  1998-01-20  |  20KB  |  753 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * Memory management
  5.   *
  6.   * (c) 1995 Bernd Schmidt
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include "config.h"
  13. #include "options.h"
  14. #include "uae.h"
  15. #include "memory.h"
  16. #include "ersatz.h"
  17. #include "zfile.h"
  18.  
  19. #ifdef USE_MAPPED_MEMORY
  20. #include <sys/mman.h>
  21. #endif
  22.  
  23. int ersatzkickfile = 0;
  24.  
  25. #ifdef SAVE_MEMORY_BANKS
  26. addrbank *mem_banks[65536];
  27. #else
  28. addrbank mem_banks[65536];
  29. #endif
  30.  
  31. #ifdef NO_INLINE_MEMORY_ACCESS
  32. __inline__ uae_u32 longget(uaecptr addr)
  33. {
  34.     return call_mem_get_func(get_mem_bank(addr).lget, addr);
  35. }
  36. __inline__ uae_u32 wordget(uaecptr addr)
  37. {
  38.     return call_mem_get_func(get_mem_bank(addr).wget, addr);
  39. }
  40. __inline__ uae_u32 byteget(uaecptr addr)
  41. {
  42.     return call_mem_get_func(get_mem_bank(addr).bget, addr);
  43. }
  44. __inline__ void longput(uaecptr addr, uae_u32 l)
  45. {
  46.     call_mem_put_func(get_mem_bank(addr).lput, addr, l);
  47. }
  48. __inline__ void wordput(uaecptr addr, uae_u32 w)
  49. {
  50.     call_mem_put_func(get_mem_bank(addr).wput, addr, w);
  51. }
  52. __inline__ void byteput(uaecptr addr, uae_u32 b)
  53. {
  54.     call_mem_put_func(get_mem_bank(addr).bput, addr, b);
  55. }
  56. #endif
  57.  
  58. uae_u32 chipmem_mask, kickmem_mask, bogomem_mask, a3000mem_mask;
  59.  
  60. /* A dummy bank that only contains zeros */
  61.  
  62. static uae_u32 dummy_lget(uaecptr) REGPARAM;
  63. static uae_u32 dummy_wget(uaecptr) REGPARAM;
  64. static uae_u32 dummy_bget(uaecptr) REGPARAM;
  65. static void  dummy_lput(uaecptr, uae_u32) REGPARAM;
  66. static void  dummy_wput(uaecptr, uae_u32) REGPARAM;
  67. static void  dummy_bput(uaecptr, uae_u32) REGPARAM;
  68. static int   dummy_check(uaecptr addr, uae_u32 size) REGPARAM;
  69.  
  70. uae_u32 REGPARAM2 dummy_lget(uaecptr addr)
  71. {
  72.     if (currprefs.illegal_mem) {
  73.     sprintf (warning_buffer, "Illegal lget at %08lx\n", addr);
  74.     write_log (warning_buffer);
  75.     }
  76.     return 0;
  77. }
  78.  
  79. uae_u32 REGPARAM2 dummy_wget(uaecptr addr)
  80. {
  81.     if (currprefs.illegal_mem) {
  82.     sprintf (warning_buffer, "Illegal wget at %08lx\n", addr);
  83.     write_log (warning_buffer);
  84.     }
  85.     return 0;
  86. }
  87.  
  88. uae_u32 REGPARAM2 dummy_bget(uaecptr addr)
  89. {
  90.     if (currprefs.illegal_mem) {
  91.     sprintf (warning_buffer, "Illegal bget at %08lx\n", addr);
  92.     write_log (warning_buffer);
  93.     }
  94.     return 0;
  95. }
  96.  
  97. void REGPARAM2 dummy_lput(uaecptr addr, uae_u32 l)
  98. {
  99.     if (currprefs.illegal_mem) {
  100.     sprintf (warning_buffer, "Illegal lput at %08lx\n", addr);
  101.     write_log (warning_buffer);
  102.     }
  103. }
  104. void REGPARAM2 dummy_wput(uaecptr addr, uae_u32 w)
  105. {
  106.     if (currprefs.illegal_mem) {
  107.     sprintf (warning_buffer, "Illegal wput at %08lx\n", addr);
  108.     write_log (warning_buffer);
  109.     }
  110. }
  111. void REGPARAM2 dummy_bput(uaecptr addr, uae_u32 b)
  112. {
  113.     if (currprefs.illegal_mem) {
  114.     sprintf (warning_buffer, "Illegal bput at %08lx\n", addr);
  115.     write_log (warning_buffer);
  116.     }
  117. }
  118.  
  119. int REGPARAM2 dummy_check(uaecptr addr, uae_u32 size)
  120. {
  121.     if (currprefs.illegal_mem) {
  122.     sprintf (warning_buffer, "Illegal check at %08lx\n", addr);
  123.     write_log (warning_buffer);
  124.     }
  125.     return 0;
  126. }
  127.  
  128. /* A3000 "motherboard resources" bank.  */
  129. static uae_u32 mbres_lget(uaecptr) REGPARAM;
  130. static uae_u32 mbres_wget(uaecptr) REGPARAM;
  131. static uae_u32 mbres_bget(uaecptr) REGPARAM;
  132. static void  mbres_lput(uaecptr, uae_u32) REGPARAM;
  133. static void  mbres_wput(uaecptr, uae_u32) REGPARAM;
  134. static void  mbres_bput(uaecptr, uae_u32) REGPARAM;
  135. static int   mbres_check(uaecptr addr, uae_u32 size) REGPARAM;
  136.  
  137. static int mbres_val = 0;
  138.  
  139. uae_u32 REGPARAM2 mbres_lget(uaecptr addr)
  140. {
  141.     if (currprefs.illegal_mem) {
  142.     sprintf (warning_buffer, "Illegal lget at %08lx\n", addr);
  143.     write_log (warning_buffer);
  144.     }
  145.     return 0;
  146. }
  147.  
  148. uae_u32 REGPARAM2 mbres_wget(uaecptr addr)
  149. {
  150.     if (currprefs.illegal_mem) {
  151.     sprintf (warning_buffer, "Illegal wget at %08lx\n", addr);
  152.     write_log (warning_buffer);
  153.     }
  154.     return 0;
  155. }
  156.  
  157. uae_u32 REGPARAM2 mbres_bget(uaecptr addr)
  158. {
  159.     if (currprefs.illegal_mem) {
  160.     sprintf (warning_buffer, "Illegal bget at %08lx\n", addr);
  161.     write_log (warning_buffer);
  162.     }
  163.     return (addr & 0xFFFF) == 3 ? mbres_val : 0;
  164. }
  165.  
  166. void REGPARAM2 mbres_lput(uaecptr addr, uae_u32 l)
  167. {
  168.     if (currprefs.illegal_mem) {
  169.     sprintf (warning_buffer, "Illegal lput at %08lx\n", addr);
  170.     write_log (warning_buffer);
  171.     }
  172. }
  173. void REGPARAM2 mbres_wput(uaecptr addr, uae_u32 w)
  174. {
  175.     if (currprefs.illegal_mem) {
  176.     sprintf (warning_buffer, "Illegal wput at %08lx\n", addr);
  177.     write_log (warning_buffer);
  178.     }
  179. }
  180. void REGPARAM2 mbres_bput(uaecptr addr, uae_u32 b)
  181. {
  182.     if (currprefs.illegal_mem) {
  183.     sprintf (warning_buffer, "Illegal bput at %08lx\n", addr);
  184.     write_log (warning_buffer);
  185.     }
  186.     if ((addr & 0xFFFF) == 3)
  187.     mbres_val = b;
  188. }
  189.  
  190. int REGPARAM2 mbres_check(uaecptr addr, uae_u32 size)
  191. {
  192.     if (currprefs.illegal_mem) {
  193.     sprintf (warning_buffer, "Illegal check at %08lx\n", addr);
  194.     write_log (warning_buffer);
  195.     }
  196.     return 0;
  197. }
  198.  
  199. /* Chip memory */
  200.  
  201. uae_u8 *chipmemory;
  202.  
  203. static uae_u32 chipmem_lget(uaecptr) REGPARAM;
  204. static uae_u32 chipmem_wget(uaecptr) REGPARAM;
  205. static uae_u32 chipmem_bget(uaecptr) REGPARAM;
  206. static void  chipmem_lput(uaecptr, uae_u32) REGPARAM;
  207. static void  chipmem_wput(uaecptr, uae_u32) REGPARAM;
  208. static void  chipmem_bput(uaecptr, uae_u32) REGPARAM;
  209.  
  210. static int   chipmem_check(uaecptr addr, uae_u32 size) REGPARAM;
  211. static uae_u8 *chipmem_xlate(uaecptr addr) REGPARAM;
  212.  
  213. uae_u32 REGPARAM2 chipmem_lget(uaecptr addr)
  214. {
  215.     uae_u32 *m;
  216.     addr -= chipmem_start & chipmem_mask;
  217.     addr &= chipmem_mask;
  218.     m = (uae_u32 *)(chipmemory + addr);
  219.     return do_get_mem_long(m);
  220. }
  221.  
  222. uae_u32 REGPARAM2 chipmem_wget(uaecptr addr)
  223. {
  224.     uae_u16 *m;
  225.     addr -= chipmem_start & chipmem_mask;
  226.     addr &= chipmem_mask;
  227.     m = (uae_u16 *)(chipmemory + addr);
  228.     return do_get_mem_word(m);
  229. }
  230.  
  231. uae_u32 REGPARAM2 chipmem_bget(uaecptr addr)
  232. {
  233.     addr -= chipmem_start & chipmem_mask;
  234.     addr &= chipmem_mask;
  235.     return chipmemory[addr];
  236. }
  237.  
  238. void REGPARAM2 chipmem_lput(uaecptr addr, uae_u32 l)
  239. {
  240.     uae_u32 *m;
  241.     addr -= chipmem_start & chipmem_mask;
  242.     addr &= chipmem_mask;
  243.     m = (uae_u32 *)(chipmemory + addr);
  244.     do_put_mem_long(m, l);
  245. }
  246.  
  247. void REGPARAM2 chipmem_wput(uaecptr addr, uae_u32 w)
  248. {
  249.     uae_u16 *m;
  250.     addr -= chipmem_start & chipmem_mask;
  251.     addr &= chipmem_mask;
  252.     m = (uae_u16 *)(chipmemory + addr);
  253.     do_put_mem_word(m, w);
  254. }
  255.  
  256. void REGPARAM2 chipmem_bput(uaecptr addr, uae_u32 b)
  257. {
  258.     addr -= chipmem_start & chipmem_mask;
  259.     addr &= chipmem_mask;
  260.     chipmemory[addr] = b;
  261. }
  262.  
  263. int REGPARAM2 chipmem_check(uaecptr addr, uae_u32 size)
  264. {
  265.     addr -= chipmem_start & chipmem_mask;
  266.     addr &= chipmem_mask;
  267.     return (addr + size) < chipmem_size;
  268. }
  269.  
  270. uae_u8 REGPARAM2 *chipmem_xlate(uaecptr addr)
  271. {
  272.     addr -= chipmem_start & chipmem_mask;
  273.     addr &= chipmem_mask;
  274.     return chipmemory + addr;
  275. }
  276.  
  277. /* Slow memory */
  278.  
  279. static uae_u8 *bogomemory;
  280.  
  281. static uae_u32 bogomem_lget(uaecptr) REGPARAM;
  282. static uae_u32 bogomem_wget(uaecptr) REGPARAM;
  283. static uae_u32 bogomem_bget(uaecptr) REGPARAM;
  284. static void  bogomem_lput(uaecptr, uae_u32) REGPARAM;
  285. static void  bogomem_wput(uaecptr, uae_u32) REGPARAM;
  286. static void  bogomem_bput(uaecptr, uae_u32) REGPARAM;
  287. static int  bogomem_check(uaecptr addr, uae_u32 size) REGPARAM;
  288. static uae_u8 *bogomem_xlate(uaecptr addr) REGPARAM;
  289.  
  290. uae_u32 REGPARAM2 bogomem_lget(uaecptr addr)
  291. {
  292.     uae_u32 *m;
  293.     addr -= bogomem_start & bogomem_mask;
  294.     addr &= bogomem_mask;
  295.     m = (uae_u32 *)(bogomemory + addr);
  296.     return do_get_mem_long(m);
  297. }
  298.  
  299. uae_u32 REGPARAM2 bogomem_wget(uaecptr addr)
  300. {
  301.     uae_u16 *m;
  302.     addr -= bogomem_start & bogomem_mask;
  303.     addr &= bogomem_mask;
  304.     m = (uae_u16 *)(bogomemory + addr);
  305.     return do_get_mem_word(m);
  306. }
  307.  
  308. uae_u32 REGPARAM2 bogomem_bget(uaecptr addr)
  309. {
  310.     addr -= bogomem_start & bogomem_mask;
  311.     addr &= bogomem_mask;
  312.     return bogomemory[addr];
  313. }
  314.  
  315. void REGPARAM2 bogomem_lput(uaecptr addr, uae_u32 l)
  316. {
  317.     uae_u32 *m;
  318.     addr -= bogomem_start & bogomem_mask;
  319.     addr &= bogomem_mask;
  320.     m = (uae_u32 *)(bogomemory + addr);
  321.     do_put_mem_long(m, l);
  322. }
  323.  
  324. void REGPARAM2 bogomem_wput(uaecptr addr, uae_u32 w)
  325. {
  326.     uae_u16 *m;
  327.     addr -= bogomem_start & bogomem_mask;
  328.     addr &= bogomem_mask;
  329.     m = (uae_u16 *)(bogomemory + addr);
  330.     do_put_mem_word(m, w);
  331. }
  332.  
  333. void REGPARAM2 bogomem_bput(uaecptr addr, uae_u32 b)
  334. {
  335.     addr -= bogomem_start & bogomem_mask;
  336.     addr &= bogomem_mask;
  337.     bogomemory[addr] = b;
  338. }
  339.  
  340. int REGPARAM2 bogomem_check(uaecptr addr, uae_u32 size)
  341. {
  342.     addr -= bogomem_start & bogomem_mask;
  343.     addr &= bogomem_mask;
  344.     return (addr + size) < bogomem_size;
  345. }
  346.  
  347. uae_u8 REGPARAM2 *bogomem_xlate(uaecptr addr)
  348. {
  349.     addr -= bogomem_start & bogomem_mask;
  350.     addr &= bogomem_mask;
  351.     return bogomemory + addr;
  352. }
  353.  
  354. /* A3000 motherboard fast memory */
  355.  
  356. static uae_u8 *a3000memory;
  357.  
  358. static uae_u32 a3000mem_lget(uaecptr) REGPARAM;
  359. static uae_u32 a3000mem_wget(uaecptr) REGPARAM;
  360. static uae_u32 a3000mem_bget(uaecptr) REGPARAM;
  361. static void  a3000mem_lput(uaecptr, uae_u32) REGPARAM;
  362. static void  a3000mem_wput(uaecptr, uae_u32) REGPARAM;
  363. static void  a3000mem_bput(uaecptr, uae_u32) REGPARAM;
  364. static int  a3000mem_check(uaecptr addr, uae_u32 size) REGPARAM;
  365. static uae_u8 *a3000mem_xlate(uaecptr addr) REGPARAM;
  366.  
  367. uae_u32 REGPARAM2 a3000mem_lget(uaecptr addr)
  368. {
  369.     uae_u32 *m;
  370.     addr -= a3000mem_start & a3000mem_mask;
  371.     addr &= a3000mem_mask;
  372.     m = (uae_u32 *)(a3000memory + addr);
  373.     return do_get_mem_long(m);
  374. }
  375.  
  376. uae_u32 REGPARAM2 a3000mem_wget(uaecptr addr)
  377. {
  378.     uae_u16 *m;
  379.     addr -= a3000mem_start & a3000mem_mask;
  380.     addr &= a3000mem_mask;
  381.     m = (uae_u16 *)(a3000memory + addr);
  382.     return do_get_mem_word(m);
  383. }
  384.  
  385. uae_u32 REGPARAM2 a3000mem_bget(uaecptr addr)
  386. {
  387.     addr -= a3000mem_start & a3000mem_mask;
  388.     addr &= a3000mem_mask;
  389.     return a3000memory[addr];
  390. }
  391.  
  392. void REGPARAM2 a3000mem_lput(uaecptr addr, uae_u32 l)
  393. {
  394.     uae_u32 *m;
  395.     addr -= a3000mem_start & a3000mem_mask;
  396.     addr &= a3000mem_mask;
  397.     m = (uae_u32 *)(a3000memory + addr);
  398.     do_put_mem_long(m, l);
  399. }
  400.  
  401. void REGPARAM2 a3000mem_wput(uaecptr addr, uae_u32 w)
  402. {
  403.     uae_u16 *m;
  404.     addr -= a3000mem_start & a3000mem_mask;
  405.     addr &= a3000mem_mask;
  406.     m = (uae_u16 *)(a3000memory + addr);
  407.     do_put_mem_word(m, w);
  408. }
  409.  
  410. void REGPARAM2 a3000mem_bput(uaecptr addr, uae_u32 b)
  411. {
  412.     addr -= a3000mem_start & a3000mem_mask;
  413.     addr &= a3000mem_mask;
  414.     a3000memory[addr] = b;
  415. }
  416.  
  417. int REGPARAM2 a3000mem_check(uaecptr addr, uae_u32 size)
  418. {
  419.     addr -= a3000mem_start & a3000mem_mask;
  420.     addr &= a3000mem_mask;
  421.     return (addr + size) < a3000mem_size;
  422. }
  423.  
  424. uae_u8 REGPARAM2 *a3000mem_xlate(uaecptr addr)
  425. {
  426.     addr -= a3000mem_start & a3000mem_mask;
  427.     addr &= a3000mem_mask;
  428.     return a3000memory + addr;
  429. }
  430.  
  431. /* Kick memory */
  432.  
  433. uae_u8 *kickmemory;
  434.  
  435. static uae_u32 kickmem_lget(uaecptr) REGPARAM;
  436. static uae_u32 kickmem_wget(uaecptr) REGPARAM;
  437. static uae_u32 kickmem_bget(uaecptr) REGPARAM;
  438. static void  kickmem_lput(uaecptr, uae_u32) REGPARAM;
  439. static void  kickmem_wput(uaecptr, uae_u32) REGPARAM;
  440. static void  kickmem_bput(uaecptr, uae_u32) REGPARAM;
  441. static int  kickmem_check(uaecptr addr, uae_u32 size) REGPARAM;
  442. static uae_u8 *kickmem_xlate(uaecptr addr) REGPARAM;
  443.  
  444. uae_u32 REGPARAM2 kickmem_lget(uaecptr addr)
  445. {
  446.     uae_u32 *m;
  447.     addr -= kickmem_start & kickmem_mask;
  448.     addr &= kickmem_mask;
  449.     m = (uae_u32 *)(kickmemory + addr);
  450.     return do_get_mem_long(m);
  451. }
  452.  
  453. uae_u32 REGPARAM2 kickmem_wget(uaecptr addr)
  454. {
  455.     uae_u16 *m;
  456.     addr -= kickmem_start & kickmem_mask;
  457.     addr &= kickmem_mask;
  458.     m = (uae_u16 *)(kickmemory + addr);
  459.     return do_get_mem_word(m);
  460. }
  461.  
  462. uae_u32 REGPARAM2 kickmem_bget(uaecptr addr)
  463. {
  464.     addr -= kickmem_start & kickmem_mask;
  465.     addr &= kickmem_mask;
  466.     return kickmemory[addr];
  467. }
  468.  
  469. void REGPARAM2 kickmem_lput(uaecptr addr, uae_u32 b)
  470. {
  471.     if (currprefs.illegal_mem) sprintf (warning_buffer, "Illegal kickmem lput at %08lx\n", addr);
  472. }
  473.  
  474. void REGPARAM2 kickmem_wput(uaecptr addr, uae_u32 b)
  475. {
  476.     if (currprefs.illegal_mem) sprintf (warning_buffer, "Illegal kickmem wput at %08lx\n", addr);
  477. }
  478.  
  479. void REGPARAM2 kickmem_bput(uaecptr addr, uae_u32 b)
  480. {
  481.     if (currprefs.illegal_mem) sprintf (warning_buffer, "Illegal kickmem lput at %08lx\n", addr);
  482. }
  483.  
  484. int REGPARAM2 kickmem_check(uaecptr addr, uae_u32 size)
  485. {
  486.     addr -= kickmem_start & kickmem_mask;
  487.     addr &= kickmem_mask;
  488.     return (addr + size) < kickmem_size;
  489. }
  490.  
  491. uae_u8 REGPARAM2 *kickmem_xlate(uaecptr addr)
  492. {
  493.     addr -= kickmem_start & kickmem_mask;
  494.     addr &= kickmem_mask;
  495.     return kickmemory + addr;
  496. }
  497.  
  498. /* Default memory access functions */
  499.  
  500. int REGPARAM2 default_check(uaecptr a, uae_u32 b)
  501. {
  502.     return 0;
  503. }
  504.  
  505. uae_u8 REGPARAM2 *default_xlate(uaecptr a)
  506. {
  507.     write_log ("Your Amiga program just did something terribly stupid\n");
  508.     uae_reset();
  509.     return kickmem_xlate (get_long (0xF80000)); /* So we don't crash. */
  510. }
  511.  
  512. static int load_kickstart(void)
  513. {
  514.     int i;
  515.     uae_u32 cksum = 0, prevck = 0;
  516.     unsigned char buffer[20];
  517.  
  518.     FILE *f = zfile_open(romfile, "rb");
  519.  
  520.     if (f == NULL) {
  521.     write_log ("No Kickstart ROM found.\n");
  522. #if defined(AMIGA)||defined(__POS__)
  523. #define USE_UAE_ERSATZ "USE_UAE_ERSATZ"
  524.     if (!getenv(USE_UAE_ERSATZ)) {
  525.     fprintf (stderr, "Using current ROM. (create ENV:%s to "
  526.         "use uae's ROM replacement)\n",USE_UAE_ERSATZ);
  527.         memcpy(kickmemory,(char*)0x1000000-kickmem_size,kickmem_size);
  528.         goto chk_sum;
  529.     }
  530. #endif
  531.     return 0;
  532.     }
  533.  
  534.     i = fread (buffer, 1, 11, f);
  535.     if (strncmp ((char *)buffer, "AMIROMTYPE1", 11) != 0)
  536.     fseek (f, 0, SEEK_SET);
  537.  
  538.     i = fread (kickmemory, 1, kickmem_size, f);
  539.     if (i == kickmem_size/2) {
  540.     memcpy (kickmemory + kickmem_size/2, kickmemory, kickmem_size/2);
  541.     } else if (i != kickmem_size) {
  542.     write_log ("Error while reading Kickstart.\n");
  543.     return 0;
  544.     }
  545.     zfile_close (f);
  546.  
  547.     cloanto_rom = 0;
  548.     if (strncmp ((char *)buffer, "AMIROMTYPE1", 11) == 0) {
  549.     FILE *keyf;
  550.     uae_u8 *p;
  551.     long size, cnt, t;
  552.  
  553.     cloanto_rom = 1;
  554.     write_log ("ROM image is an encrypted \"Amiga Forever\" ROM file.\n");
  555.     if (strlen (keyfile) == 0) {
  556.         write_log ("No filename given for ROM key file.\n");
  557.         return 0;
  558.     }
  559.     keyf = zfile_open (keyfile, "rb");
  560.     if (keyf == 0) {
  561.         write_log ("Could not find ROM key file.\n");
  562.         return 0;
  563.     }
  564.     p = (uae_u8 *)xmalloc (524288);
  565.     size = fread (p, 1, 524288, keyf);
  566.  
  567.     for (t = cnt = 0; cnt < kickmem_size; cnt++, t = (t + 1) % size) {
  568.         kickmemory[cnt] ^= p[t];
  569.         if (i == cnt+1)
  570.         t = size-1;
  571.     }
  572.     fclose (keyf);
  573.     free (p);
  574.     }
  575. #if defined(AMIGA)
  576.     chk_sum:
  577. #endif
  578.  
  579.     for (i = 0; i < kickmem_size; i+=4) {
  580.     uae_u32 data = kickmemory[i]*65536*256 + kickmemory[i+1]*65536 + kickmemory[i+2]*256 + kickmemory[i+3];
  581.     cksum += data;
  582.     if (cksum < prevck)
  583.         cksum++;
  584.     prevck = cksum;
  585.     }
  586.     if (cksum != 0xFFFFFFFFul) {
  587.     write_log("Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
  588.     }
  589.     return 1;
  590. }
  591.  
  592. /* Address banks */
  593.  
  594. addrbank dummy_bank = {
  595.     dummy_lget, dummy_wget, dummy_bget,
  596.     dummy_lput, dummy_wput, dummy_bput,
  597.     default_xlate, dummy_check
  598. };
  599.  
  600. addrbank mbres_bank = {
  601.     mbres_lget, mbres_wget, mbres_bget,
  602.     mbres_lput, mbres_wput, mbres_bput,
  603.     default_xlate, mbres_check
  604. };
  605.  
  606. addrbank chipmem_bank = {
  607.     chipmem_lget, chipmem_wget, chipmem_bget,
  608.     chipmem_lput, chipmem_wput, chipmem_bput,
  609.     chipmem_xlate, chipmem_check
  610. };
  611.  
  612. addrbank bogomem_bank = {
  613.     bogomem_lget, bogomem_wget, bogomem_bget,
  614.     bogomem_lput, bogomem_wput, bogomem_bput,
  615.     bogomem_xlate, bogomem_check
  616. };
  617.  
  618. addrbank a3000mem_bank = {
  619.     a3000mem_lget, a3000mem_wget, a3000mem_bget,
  620.     a3000mem_lput, a3000mem_wput, a3000mem_bput,
  621.     a3000mem_xlate, a3000mem_check
  622. };
  623.  
  624. addrbank kickmem_bank = {
  625.     kickmem_lget, kickmem_wget, kickmem_bget,
  626.     kickmem_lput, kickmem_wput, kickmem_bput,
  627.     kickmem_xlate, kickmem_check
  628. };
  629.  
  630. char *address_space, *good_address_map;
  631. int good_address_fd;
  632. #define MAKE_USER_PROGRAMS_BEHAVE 1
  633. void memory_init(void)
  634. {
  635.     char buffer[4096];
  636.     char *nam;
  637.     int i, fd;
  638.     int custom_start;
  639.  
  640.     chipmem_mask = chipmem_size - 1;
  641.     kickmem_mask = kickmem_size - 1;
  642.     bogomem_mask = bogomem_size - 1;
  643.     a3000mem_mask = a3000mem_size - 1;
  644.  
  645. #ifdef USE_MAPPED_MEMORY
  646.     fd = open("/dev/zero", O_RDWR);
  647.     good_address_map = mmap(NULL, 1 << 24, PROT_READ, MAP_PRIVATE, fd, 0);
  648.     /* Don't believe USER_PROGRAMS_BEHAVE. Otherwise, we'd segfault as soon
  649.      * as a decrunch routine tries to do color register hacks. */
  650.     address_space = mmap(NULL, 1 << 24, PROT_READ | (USER_PROGRAMS_BEHAVE || MAKE_USER_PROGRAMS_BEHAVE? PROT_WRITE : 0), MAP_PRIVATE, fd, 0);
  651.     if ((int)address_space < 0 || (int)good_address_map < 0) {
  652.     write_log ("Your system does not have enough virtual memory - increase swap.\n");
  653.     abort();
  654.     }
  655. #ifdef MAKE_USER_PROGRAMS_BEHAVE
  656.     memset(address_space + 0xDFF180, 0xFF, 32*2);
  657. #else
  658.     /* Likewise. This is mostly for mouse button checks. */
  659.     if (USER_PROGRAMS_BEHAVE)
  660.     memset(address_space + 0xA00000, 0xFF, 0xF00000 - 0xA00000);
  661. #endif
  662.     chipmemory = mmap(address_space, 0x200000, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0);
  663.     kickmemory = mmap(address_space + 0xF80000, 0x80000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0);
  664.  
  665.     close(fd);
  666.  
  667.     good_address_fd = open(nam = tmpnam (NULL), O_CREAT|O_RDWR, 0600);
  668.     memset (buffer,1,sizeof(buffer));
  669.     write (good_address_fd, buffer, sizeof buffer);
  670.     unlink (nam);
  671.  
  672.     for (i = 0; i < chipmem_size; i += 4096)
  673.     mmap(good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE,
  674.          good_address_fd, 0);
  675.     for (i = 0; i < kickmem_size; i += 4096)
  676.     mmap(good_address_map + i + 0x1000000 - kickmem_size, 4096, PROT_READ,
  677.          MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
  678. #else
  679.     kickmemory = (uae_u8 *)xmalloc(kickmem_size);
  680.     chipmemory = (uae_u8 *)malloc(chipmem_size);
  681.  
  682.     while (!chipmemory && chipmem_size > 512*1024) {
  683.     chipmem_size >>= 1;
  684.     chipmem_mask = chipmem_size - 1;
  685.     chipmemory = (uae_u8 *)malloc(chipmem_size);
  686.     if (chipmemory)
  687.         fprintf (stderr, "Reducing chipmem size to %dkb\n", chipmem_size>>10);
  688.     }
  689.     if (!chipmemory) {
  690.     write_log ("virtual memory exhausted (chipmemory)!\n");
  691.     abort();
  692.     }
  693. #endif
  694.  
  695.     for(i = 0; i < 65536; i++)
  696.     put_mem_bank (i<<16, &dummy_bank);
  697.  
  698.     /* Map the chipmem into all of the lower 16MB */
  699.     map_banks (&chipmem_bank, 0x00, 256);
  700.     custom_start = 0xC0;
  701.  
  702.     map_banks (&custom_bank, custom_start, 0xE0-custom_start);
  703.     map_banks (&cia_bank, 0xA0, 32);
  704.     map_banks (&clock_bank, 0xDC, 1);
  705.  
  706.     /* @@@ Does anyone have a clue what should be in the 0x200000 - 0xA00000
  707.      * range on an Amiga without expansion memory?  */
  708.     custom_start = chipmem_size >> 16;
  709.     if (custom_start < 0x20)
  710.     custom_start = 0x20;
  711.     map_banks (&dummy_bank, custom_start, 0xA0 - custom_start);
  712.     /*map_banks (&mbres_bank, 0xDE, 1);*/
  713.  
  714.     if (bogomem_size > 0) {
  715.     bogomemory = (uae_u8 *)xmalloc (bogomem_size);
  716.     map_banks(&bogomem_bank, 0xC0, bogomem_size >> 16);
  717.     }
  718.  
  719.     if (a3000mem_size > 0) {
  720.     a3000memory = (uae_u8 *)xmalloc (a3000mem_size);
  721.     map_banks(&a3000mem_bank, a3000mem_start >> 16, a3000mem_size >> 16);
  722.     }
  723.  
  724.     map_banks (&rtarea_bank, 0xF0, 1);
  725.     if (!load_kickstart ()) {
  726.     init_ersatz_rom (kickmemory);
  727.     ersatzkickfile = 1;
  728.     }
  729.     map_banks (&kickmem_bank, 0xF8, 8);
  730.     map_banks (&expamem_bank, 0xE8, 1);
  731.  
  732.     if (cloanto_rom)
  733.     map_banks (&kickmem_bank, 0xE0, 8);
  734. }
  735.  
  736. void map_banks(addrbank *bank, int start, int size)
  737. {
  738.     int bnr;
  739.     unsigned long int hioffs = 0, endhioffs = 0x100;
  740.  
  741.     if (start >= 0x100) {
  742.     for (bnr = start; bnr < start + size; bnr++)
  743.         put_mem_bank (bnr << 16, bank);
  744.     return;
  745.     }
  746.     /* Some '020 Kickstarts apparently require a 24 bit address space... */
  747.     if (CPU_LEVEL < 2 || address_space_24)
  748.     endhioffs = 0x10000;
  749.     for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100)
  750.     for (bnr = start; bnr < start+size; bnr++)
  751.         put_mem_bank((bnr + hioffs) << 16, bank);
  752. }
  753.